package org.eminem.mybaitsplus.generator;

import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.core.exceptions.MybatisPlusException;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.InjectionConfig;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.converts.MySqlTypeConvert;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.baomidou.mybatisplus.generator.config.rules.DbColumnType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
import com.baomidou.mybatisplus.generator.engine.VelocityTemplateEngine;

import java.io.File;
import java.util.*;

/**
 * <p>
 * mysql 代码生成器演示例子
 * </p>
 *
 * @author eminem
 * @since 2019-08-23
 */
public class MysqlGenerator {

    /**
     * <p>
     * 读取控制台内容
     * </p>
     */
    public static String scanner(String tip) {
        Scanner scanner = new Scanner(System.in);
        StringBuilder help = new StringBuilder();
        help.append("请输入" + tip + "：");
        System.out.println(help.toString());
        if (scanner.hasNext()) {
            String ipt = scanner.next();
            if (StringUtils.isNotEmpty(ipt)) {
                return ipt;
            }
        }
        throw new MybatisPlusException("请输入正确的" + tip + "！");
    }

    /**
     * RUN THIS
     */
    public static void main(String[] args) {
        //获取工程目录
        String projectPath = System.getProperty("user.dir");
        System.out.println("projectPath:"+projectPath);
        String outPutPath = projectPath +
                File.separator+"mybatis-plus-generator"
                +File.separator+"src"
                +File.separator+"main"
                +File.separator+"java";
        System.out.println("outPutPath:"+outPutPath);
        String resourcesPath = projectPath +
                File.separator+"mybatis-plus-generator"
                +File.separator+"src"
                +File.separator+"main"
                +File.separator+"resources";
        String templatePath = resourcesPath + File.separator+"templates";


        // 代码生成器
        AutoGenerator mpg = new AutoGenerator();
        mpg.setGlobalConfig(//全局配置
                 new GlobalConfig()
                 .setOutputDir(outPutPath)//设置输出目录
                 .setAuthor("eminem") //设置作者
                 .setOpen(false) //是否打开输出目录
                 .setFileOverride(true) //是否覆盖已有文件
                 .setEnableCache(false)//是否在xml中添加二级缓存配置
                 .setActiveRecord(true) //开启 ActiveRecord 模式
                 .setDateType(DateType.ONLY_DATE) //时间类型对应策略(只使用 java.util.date 代替)
                 // 自定义文件命名，注意 %s 会自动填充表实体属性！
                 .setEntityName("%sEntity") //根据表名自动生成k
                 .setMapperName("%sMapper")
                 .setXmlName("%sMapper")
                 .setServiceName("%sService")
                 .setServiceImplName("%sServiceImpl")
                 .setControllerName("%sController")
                 .setIdType(IdType.INPUT) //主键id用户输入
                 .setSwagger2(true) //开启swagger模式
        ).setPackageInfo(new PackageConfig() //包名配置
                .setModuleName(scanner("模块名")) //模块名
                .setParent("org.eminem.mybatisplus")// 自定义包路径(父包名。如果为空，将下面子包名必须写全部， 否则就只需写子包名)
                .setController("controller")// 这里是控制器包名，默认 web
                .setEntity("entity") //实体包名
                .setMapper("mapper") //mapper包名
                .setService("service") //service包名
                .setServiceImpl("service.impl") //service实现类包名
        ).setDataSource( // 数据源配置
                new DataSourceConfig()
                        .setDbType(DbType.MYSQL)// 数据库类型
                        .setTypeConvert(new MySqlTypeConvert() {
                            // 自定义数据库表字段类型转换【可选】
                            @Override
                            public DbColumnType processTypeConvert(GlobalConfig globalConfig, String fieldType) {
                                System.out.println("转换类型：" + fieldType);
                                if ( fieldType.toLowerCase().contains( "tinyint" ) ) {
                                    return DbColumnType.BOOLEAN;
                                }
                                if ( fieldType.toLowerCase().contains( "datetime" ) ) {
                                    return DbColumnType.DATE;
                                }
                                return (DbColumnType) super.processTypeConvert(globalConfig, fieldType);
                            }
                        })
                        .setDriverName("com.mysql.jdbc.Driver")
                        .setUsername("root")
                        .setPassword("123456")
                        .setUrl("jdbc:mysql://localhost:3306/test?useUnicode=true&useSSL=false&characterEncoding=utf8&serverTimezone=GMT%2B8")
        ).setStrategy(new StrategyConfig() //数据库表配置
          .setNaming(NamingStrategy.underline_to_camel) //数据库表映射到实体的命名策略
                .setEntityLombokModel(true)//【实体】是否为lombok模型（默认 false）
                .setRestControllerStyle(true) //生成 @RestController 控制器
                .setInclude(scanner("表名，多个英文逗号分割").split(",")) // 需要生成的表
                .setColumnNaming(NamingStrategy.underline_to_camel) //数据库表字段映射到实体的命名策略, 未指定按照 naming 执行
                .setEntityTableFieldAnnotationEnable(true)// 是否生成实体时，生成字段注解
        ).setCfg(
                // 注入自定义配置，可以在 VM 中使用 cfg.abc 设置的值
                new InjectionConfig() {
                    @Override
                    public void initMap() {
                        Map<String, Object> map = new HashMap<>();
                        map.put("abc", this.getConfig().getGlobalConfig().getAuthor() + "-mp");
                        this.setMap(map);
                    }
                }.setFileOutConfigList(Collections.<FileOutConfig>singletonList(new FileOutConfig(
                        "/templates/mapper.xml.vm"

                ) {
                    // 自定义输出文件目录
                    @Override
                    public String outputFile(TableInfo tableInfo) {
                        return resourcesPath+File.separator+"mapper/"+ mpg.getPackageInfo().getModuleName()  + "/" + tableInfo.getXmlName() + StringPool.DOT_XML;
                    }
                }))
        ).setTemplate(// 关闭默认 xml 生成，调整生成 至 根目录
                new TemplateConfig().setXml(null)
                // 自定义模板配置，模板可以参考源码 /mybatis-plus/src/main/resources/template 使用 copy
                // 至您项目 src/main/resources/template 目录下，模板名称也可自定义如下配置：
                 .setController("templates/"+"controller.java")
                 .setEntity("templates/"+"entity.java")
                 .setMapper("templates/"+"mapper.java")
                 .setService("templates/"+"service.java")
                 .setServiceImpl("templates/"+"serviceImpl.java")
        ).setTemplateEngine(new VelocityTemplateEngine()) //定义生成模板类型
        ;
        mpg.execute();

    }

}
